//go:build test

package main

import (
	"fmt"
	"net/http"
	"sync"
	"time"
)

func main() {
	fmt.Println("Proxy Performance Benchmark")
	fmt.Println("============================")

	// Test proxy endpoint
	proxyURL := "http://localhost:8001"

	// Test URLs to benchmark
	testURLs := []string{
		"https://httpbin.org/get",
		"https://google.com",
		"https://github.com",
	}

	numRequests := 100
	numConcurrent := 10

	for _, url := range testURLs {
		fmt.Printf("\nBenchmarking %s through proxy\n", url)
		fmt.Printf("Requests: %d, Concurrency: %d\n", numRequests, numConcurrent)

		// Test without proxy first
		start := time.Now()
		err := benchmarkURL(url, "", numRequests, numConcurrent)
		duration := time.Since(start)

		if err != nil {
			fmt.Printf("Error without proxy: %v\n", err)
		} else {
			fmt.Printf("Without proxy: %v (%.2f req/sec)\n", duration, float64(numRequests)/duration.Seconds())
		}

		// Test with proxy
		start = time.Now()
		err = benchmarkURL(url, proxyURL, numRequests, numConcurrent)
		duration = time.Since(start)

		if err != nil {
			fmt.Printf("Error with proxy: %v\n", err)
		} else {
			fmt.Printf("With proxy: %v (%.2f req/sec)\n", duration, float64(numRequests)/duration.Seconds())
		}
	}
}

func benchmarkURL(url, proxyURL string, numRequests, concurrency int) error {
	client := &http.Client{}

	if proxyURL != "" {
		client.Transport = &http.Transport{
			Proxy: http.ProxyURL(parseURL(proxyURL)),
		}
	}

	var wg sync.WaitGroup
	var errors []error
	var mu sync.Mutex

	semaphore := make(chan struct{}, concurrency)

	for i := 0; i < numRequests; i++ {
		wg.Add(1)
		semaphore <- struct{}{}

		go func() {
			defer wg.Done()
			defer func() { <-semaphore }()

			resp, err := client.Get(url)
			if err != nil {
				mu.Lock()
				errors = append(errors, err)
				mu.Unlock()
				return
			}
			resp.Body.Close()
		}()
	}

	wg.Wait()

	if len(errors) > 0 {
		return fmt.Errorf("%d errors occurred, first error: %v", len(errors), errors[0])
	}

	return nil
}

func parseURL(s string) *http.URL {
	u, err := http.ParseURL(s)
	if err != nil {
		panic(err)
	}
	return u
}
